define(['app', 'json5', 'clipboard', 'jquery.format'], function(app, JSON5, Clipboard) {
    app.controller('TestMockController', function($http, $timeout, $scope, $compile, xContext, $uibModalInstance,
            xDialog, xUtil, toastr) {
        var self = this;
        self.url = '';
        self.method = 'GET';
        self.response = null;
        self.parsable = true;
        self.completed = true;

        var editor = null,
            viewer = null;
        self.fullScreen = false;
        self.fullScreen2 = false;

        var headers = {};

        self.init = function() {
            var path = xUtil.regex.urlMatch(xContext.data, xContext.path);
            if (/^http(s)?:\/\//.test(path)) {
                self.url = path;
            } else {
                self.url = xUtil.host.get() + path;
            }

            self.method = xUtil.regex.subMatch(xContext.data, /^@Method：([A-Za-z]+)/gmi).toUpperCase();
            self.method = (self.method == '' ? 'GET' : self.method);

            try {
                headers = JSON5.parse(xUtil.regex.keyMatch(xContext.data, 'Headers') || '{}');
            } catch (e) {
                toastr.error('解析【Headers】错误：' + e);
            }

            var requestBody = xUtil.regex.keyMatch(xContext.data, '入参');

            const maxHeight = 200;
            // data editor
            editor = ace.edit('data-request');
            editor.setOptions({
                mode: 'ace/mode/' + (xContext.extname == '.json' ? 'hjson' : 'xml'),
                fontSize: 13,
                maxPixelHeight: maxHeight,
                showPrintMargin: false,
                autoScrollEditorIntoView: true,
                enableBasicAutocompletion: true,
                enableSnippets: true,
                enableLiveAutocompletion: true,
                tooltipOffset: function() {
                    return jQuery(editor.container).parents('.modal-dialog').offset();
                }
            });
            if (xContext.extname == '.json') {
                editor.setValue('/*支持JSON5格式与注释*/\n');
            } else if (xContext.extname == '.xml') {
                editor.setValue('<!--支持XML注释-->\n');
            }
            editor.getSession().on('changeAnnotation', function(e) {
                // check errors
                $timeout(function() {
                    var annotations = editor.getSession().getAnnotations();
                    var parsable = true;
                    if (!_.isEmpty(annotations)) {
                        if (_.find(annotations, function(annotation) {
                            return annotation.type == 'error';
                        })) {
                            parsable = false;
                        }
                    }
                    if (self.parsable != parsable) {
                        self.parsable = parsable;
                    }
                });
            });
            // add request body
            editor.gotoLine(2);
            editor.insert(requestBody);

            // data viewer
            viewer = ace.edit('data-response');
            viewer.setOptions({
                mode: 'ace/mode/text',
                fontSize: 13,
                useWorker: false,
                readOnly: true,
                showPrintMargin: false,
                highlightActiveLine: false,
                autoScrollEditorIntoView: true
            });

            // request body tools
            jQuery('#data-request .ace_scroller').append($compile(jQuery('#json-tools').html())($scope));
            // response body tools
            jQuery('#data-response .ace_scroller').append($compile(jQuery('#view-tools').html())($scope));
            // disable click event of tools
            jQuery('.x-editor-tool').mousedown(function(e) { return false; });
            // full screen
            var dlgMockTest = jQuery('[name="frmMock"]').parents('.modal-dialog');
            var resizeTestDialog = function(fullScreen) {
                if (fullScreen) {
                    dlgMockTest.css('height', dlgMockTest.height());
                } else {
                    dlgMockTest.css('height', '');
                }
            }
            $scope.$watch('dvm.fullScreen', function(fullScreen) {
                resizeTestDialog(fullScreen);
                setTimeout(function() {
                    editor.resize();
                }, 50);
            });
            $scope.$watch('dvm.fullScreen2', function(fullScreen) {
                resizeTestDialog(fullScreen);
                setTimeout(function() {
                    viewer.resize();
                }, 50);
            });

            jQuery('#data-request, #data-response').height(maxHeight);

            $scope.$watch('dvm.method', function(newValue) {
                if (newValue != 'GET') {
                    editor.focus();
                }
            });

            $scope.$watch('dvm.response', function(newValue) {
                if (newValue == null || newValue.data == null) {
                    viewer.setValue('', -1);
                } else {
                    var modeId = 'ace/mode/' + newValue.mode;
                    if (modeId != viewer.getOption('mode')) {
                        viewer.getSession().setMode(modeId);
                    }
                    viewer.setValue(newValue.data, -1);
                }
                viewer.resize();
            });

            new Clipboard('#copy-response', {
                text: function() {
                    return viewer.getValue();
                }
            }).on('success', function(e) {
                toastr.success('已复制到剪贴板！');
            });
        }

        self.send = function(valid) {
            self.response = null;
            if (valid) {
                // send request
                if (self.method == 'GET' || self.parsable) {
                    self.completed = false;

                    var body = null;
                    if (self.method != 'GET' && editor.getValue() != '') {
                        if (xContext.extname == '.json') {
                            body = JSON.stringify(JSON5.parse(editor.getValue()));
                        } else if (xContext.extname == '.xml') {
                            body = jQuery.format(editor.getValue(), { method: 'xmlmin' }).trim();
                        }
                    }

                    $http({
                        url: '/mock/test/send',
                        method: 'POST',
                        headers: {
                            'Pragma': 'no-cache',
                            'Cache-Control': 'no-cache',
                            'Content-Type': 'application/json;charset=UTF-8'
                        },
                        timeout: 35000,
                        data: {
                            url: self.url,
                            method: self.method,
                            headers: headers,
                            data: body,
                            type: (xContext.extname == '.json' ? 'json' : 'xml')
                        },
                        transformResponse: function(response) {
                            return response;
                        }
                    }).then(function(response) {
                        self.completed = true;
                        if (response.status != 200 && _.isEmpty(response.data)) {
                            xDialog.alert('错误信息', '服务器的返回信息：' + response.statusText);
                        } else {
                            if (/\/json/.test(response.headers('Content-Type'))) {
                                self.response = {
                                    mode: 'json',
                                    data: jQuery.format(response.data, { method: 'json' })
                                };
                            } else if (/\/xml/.test(response.headers('Content-Type'))) {
                                self.response = {
                                    mode: 'xml',
                                    data: jQuery.format(response.data, { method: 'xml' })
                                };
                            } else {
                                self.response = { mode: 'text', data: response.data };
                            }
                        }
                    }, function(response) {
                        self.completed = true;
                    });

                    toastr.success('测试请求已发送！');
                }
            }
        }

        self.close = function() {
            $uibModalInstance.close();
        }
    });
});
